package com.ruoyi.system.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.domain.entity.Approve;
import com.ruoyi.common.core.domain.entity.ApproveMission;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.mapper.ApproveMapper;
import com.ruoyi.system.mapper.ApproveMissionMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.system.service.ApproveService;
import com.ruoyi.system.service.IStorePanService;
import com.ruoyi.system.service.enums.ApproveActivityType;
import com.ruoyi.system.service.enums.ApproveStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author：liyouxin
 * @date：2023/8/15 18:22
 */
@Service
public class ApproveServiceImpl implements ApproveService {
    @Resource
    private ApproveMapper approveMapper;

    @Resource
    private ApproveMissionMapper approveMissionMapper;

    @Resource
    IStorePanService storePanService;

    @Resource
    private SysUserPostMapper sysUserPostMapper;

    @Override
    public List<ApproveMission> getNeedMeByUserId(Long userId) {
        Approve query = Approve.builder()
                .approver(userId)
                .build();
        List<Approve> approveList = approveMapper.selectNotApprovedList(query);
        if (CollectionUtils.isEmpty(approveList)) {
            return Collections.emptyList();
        }
        Set<Long> missionIds = approveList.stream().map(Approve::getMissionId).collect(Collectors.toSet());
        List<ApproveMission> approveMissions = approveMissionMapper.selectByIds(new ArrayList<>(missionIds));
        PageInfo<Approve> approvePageInfo = new PageInfo<>(approveList);
        Page<ApproveMission> page = new Page<>();
        page.setTotal(approvePageInfo.getTotal());
        page.addAll(approveMissions);
        return page;
    }

    @Override
    public List<ApproveMission> getNeedMeAlreadyByUserId(Long userId) {
        Approve query = Approve.builder()
                .approver(userId)
                .build();
        List<Approve> approveList = approveMapper.selectApprovedList(query);
        if (CollectionUtils.isEmpty(approveList)) {
            return Collections.emptyList();
        }
        Set<Long> missionIds = approveList.stream().map(Approve::getMissionId).collect(Collectors.toSet());
        List<ApproveMission> approveMissions = approveMissionMapper.selectByIds(new ArrayList<>(missionIds));
        PageInfo<Approve> approvePageInfo = new PageInfo<>(approveList);
        Page<ApproveMission> page = new Page<>();
        page.setTotal(approvePageInfo.getTotal());
        page.addAll(approveMissions);
        return page;
    }

    @Override
    public List<ApproveMission> getApply(ApproveMission approveMission) {
        ;
        return approveMissionMapper.selectApproveMissionList(approveMission);
    }

    @Override
    public ApproveMission getByActivityd(Long activityId, String activityType) {
        ApproveMission query = ApproveMission.builder()
                .activityType(activityType)
                .activityId(activityId).build();
        List<ApproveMission> approveMissions = approveMissionMapper.selectApproveMissionList(query);
        if (CollectionUtils.isEmpty(approveMissions)) {
            return null;
        } else {
            return approveMissions.get(0);
        }
    }

    @Override
    public List<Approve> getByMissionId(Long id) {
        ApproveMission approveMission = approveMissionMapper.selectById(id);
        if (approveMission == null) {
            return Collections.emptyList();
        }
        return approveMapper.selectApproveList(Approve.builder()
                .missionId(id)
                .build());
    }

    @Override
    public List<Approve> getApproveByActivityd(Long activityId, String activityType) {
        Approve query = Approve.builder()
                .activityId(activityId)
                .activityType(activityType)
                .build();
        return approveMapper.selectApproveList(query);
    }

    @Override
    public ApproveMission getApproveMissionByActivityd(Long activityId, String activityType) {
        ApproveMission query = ApproveMission.builder()
                .activityId(activityId)
                .activityType(activityType)
                .build();
        List<ApproveMission> approveMissions = approveMissionMapper.selectApproveMissionList(query);
        if (CollectionUtils.isEmpty(approveMissions)) {
            return null;
        }
        return approveMissions.get(0);
    }

    @Override
    public ApproveMission createApproveMission(ApproveMission approveMission) {
        approveMissionMapper.insertApproveMission(approveMission);
        if ("垃圾记录详情审批".equals(approveMission.getActivityType())) {
            handleGarbageRecordApprove(approveMission);
        } else if ("菜品信息详情审批".equals(approveMission.getActivityType())) {
            handleGoodsDetailApprove(approveMission);
        } else if ("点餐菜单审批".equals(approveMission.getActivityType())) {
            handleNormalApprove(approveMission);
        } else if ("自助餐菜单详情审批".equals(approveMission.getActivityType())) {
            handleBuffetApprove(approveMission);
        } else if ("采购计划详情审批".equals(approveMission.getActivityType())) {
            handleStorePlanApprove(approveMission);
        } else if ("代购菜单审批".equals(approveMission.getActivityType())) {
            handleReplaceApprove(approveMission);
        } else if ("考核记录审批".equals(approveMission.getActivityType())) {
            handleExaminePlanApprove(approveMission);
        } else if ("能耗记录审批".equals(approveMission.getActivityType())) {
            handleEnergyRecordApprove(approveMission);
        } else if ("盘点审批".equals(approveMission.getActivityType())) {
            handlePanRecordApprove(approveMission);
        }
        return approveMission;
    }

    private void handlePanRecordApprove(ApproveMission approveMission) {
        Approve approve = new Approve();
        approve.setActivityId(approveMission.getActivityId());
        approve.setActivityType(approveMission.getActivityType());
        approve.setApplicant(SecurityUtils.getUserId());
//        approve.setApprover(getKeepKeZhang());
        approve.setApprover(approveMission.getApprover());
        approve.setStatus("审批中");
        approve.setMissionId(approveMission.getId());
        approve.setName("盘点审批");
        approveMapper.insertApprove(approve);
    }

    private void handleEnergyRecordApprove(ApproveMission approveMission) {
        Approve approve = new Approve();
        approve.setActivityId(approveMission.getActivityId());
        approve.setActivityType(approveMission.getActivityType());
        approve.setApplicant(SecurityUtils.getUserId());
        approve.setApprover(getKezhang(getDept(SecurityUtils.getUserId())));
        approve.setStatus("审批中");
        approve.setMissionId(approveMission.getId());
        approve.setName("能耗记录科长审批");
        approveMapper.insertApprove(approve);
    }

    @Resource
    private SysUserMapper sysUserMapper;

    private void handleExaminePlanApprove(ApproveMission approveMission) {
        Approve approve = new Approve();
        approve.setActivityId(approveMission.getActivityId());
        approve.setActivityType(approveMission.getActivityType());
        approve.setApplicant(SecurityUtils.getUserId());
        approve.setApprover(getKezhang(Optional.ofNullable(sysUserMapper.selectUserById(SecurityUtils.getUserId())).map(SysUser::getDeptId).orElse(104L)));
        approve.setStatus("审批中");
        approve.setMissionId(approveMission.getId());
        approve.setName("考核记录科长审批");
        approveMapper.insertApprove(approve);
    }

    private Long getShouYin() {
        Long approver = 1L;
        List<Long> userIds = sysUserPostMapper.getUserByPostId(10L);
        if (CollectionUtils.isEmpty(userIds)) {
            return approver;
        }
        Long[] userIdsArray = new Long[userIds.size()];
        for (int i = 0; i < userIds.size(); i++) {
            userIdsArray[i] = userIds.get(i);
        }
        List<SysUser> sysUsers = sysUserMapper.selectUserByUserIdsAndDeptId(userIdsArray, 103L);
        if (CollectionUtils.isEmpty(sysUsers)) {
            return approver;
        }
        approver = sysUsers.get(0).getUserId();
        return approver;
    }

    private Long getKeepKeZhang() {
        Long approver = 1L;
        List<Long> userIds = sysUserPostMapper.getUserByPostId(7L);
        if (CollectionUtils.isEmpty(userIds)) {
            return approver;
        }
        Long[] userIdsArray = new Long[userIds.size()];
        for (int i = 0; i < userIds.size(); i++) {
            userIdsArray[i] = userIds.get(i);
        }
        List<SysUser> sysUsers = sysUserMapper.selectUserByUserIdsAndDeptId(userIdsArray, 103L);
        if (CollectionUtils.isEmpty(sysUsers)) {
            return approver;
        }
        approver = sysUsers.get(0).getUserId();
        return approver;
    }

    private Long getExaminePlanKeZhang() {
        Long approver = 1L;
        List<Long> userIds = sysUserPostMapper.getUserByPostId(7L);
        if (CollectionUtils.isEmpty(userIds)) {
            return approver;
        }
        Long[] userIdsArray = new Long[userIds.size()];
        for (int i = 0; i < userIds.size(); i++) {
            userIdsArray[i] = userIds.get(i);
        }
        List<SysUser> sysUsers = sysUserMapper.selectUserByUserIdsAndDeptId(userIdsArray, 201L);
        if (CollectionUtils.isEmpty(sysUsers)) {
            return approver;
        }
        approver = sysUsers.get(0).getUserId();
        return approver;
    }

    private Long getDept(Long userId) {
        return Optional.ofNullable(sysUserMapper.selectUserById(SecurityUtils.getUserId())).map(SysUser::getDeptId).orElse(104L);
    }

    private Long getFuKezhang(Long deptId) {
        Long approver = 1L;
        List<Long> userIds = sysUserPostMapper.getUserByPostId(8L);
        if (CollectionUtils.isEmpty(userIds)) {
            return approver;
        }
        Long[] userIdsArray = new Long[userIds.size()];
        for (int i = 0; i < userIds.size(); i++) {
            userIdsArray[i] = userIds.get(i);
        }
        List<SysUser> sysUsers = sysUserMapper.selectUserByUserIdsAndDeptId(userIdsArray, deptId);
        if (CollectionUtils.isEmpty(sysUsers)) {
            return approver;
        }
        approver = sysUsers.get(0).getUserId();
        return approver;
    }

    private Long getKezhang(Long deptId) {
        Long approver = 1L;
        List<Long> userIds = sysUserPostMapper.getUserByPostId(7L);
        if (CollectionUtils.isEmpty(userIds)) {
            return approver;
        }
        Long[] userIdsArray = new Long[userIds.size()];
        for (int i = 0; i < userIds.size(); i++) {
            userIdsArray[i] = userIds.get(i);
        }
        List<SysUser> sysUsers = sysUserMapper.selectUserByUserIdsAndDeptId(userIdsArray, deptId);
        if (CollectionUtils.isEmpty(sysUsers)) {
            return approver;
        }
        approver = sysUsers.get(0).getUserId();
        return approver;
    }

    private Long getExaminePlanFuZhuRen() {
        Long approver = 1L;
        List<Long> userIds = sysUserPostMapper.getUserByPostId(6L);
        if (CollectionUtils.isEmpty(userIds)) {
            return approver;
        }
        Long[] userIdsArray = new Long[userIds.size()];
        for (int i = 0; i < userIds.size(); i++) {
            userIdsArray[i] = userIds.get(i);
        }
        List<SysUser> sysUsers = sysUserMapper.selectUserByUserIdsAndDeptId(userIdsArray, 201L);
        if (CollectionUtils.isEmpty(sysUsers)) {
            return approver;
        }
        approver = sysUsers.get(0).getUserId();
        return approver;
    }

    private void handleReplaceApprove(ApproveMission approveMission) {
        Long approver = null;
        // 选择厨师长审批
        List<Long> userId = sysUserPostMapper.getUserByPostId(11L);
        if (CollectionUtils.isEmpty(userId)) {
            approver = 1L;
        } else {
            approver = userId.get(0);
        }
        Approve approve = new Approve();
        approve.setActivityId(approveMission.getActivityId());
        approve.setActivityType(approveMission.getActivityType());
        approve.setApplicant(SecurityUtils.getUserId());
        approve.setApprover(approver);
        approve.setStatus("审批中");
        approve.setMissionId(approveMission.getId());
        approve.setName("代购菜单厨师长审批");
        approveMapper.insertApprove(approve);
    }

    private void handleStorePlanApprove(ApproveMission approveMission) {
        Long approver = null;
        // 选择厨师长审批
        List<Long> userId = sysUserPostMapper.getUserByPostId(11L);
        if (CollectionUtils.isEmpty(userId)) {
            approver = 1L;
        } else {
            approver = userId.get(0);
        }
        Approve approve = new Approve();
        approve.setActivityId(approveMission.getActivityId());
        approve.setActivityType(approveMission.getActivityType());
        approve.setApplicant(SecurityUtils.getUserId());
        approve.setApprover(approver);
        approve.setStatus("审批中");
        approve.setMissionId(approveMission.getId());
        approve.setName("自助餐菜单厨师长审批");
        approveMapper.insertApprove(approve);
    }

    private void handleBuffetApprove(ApproveMission approveMission) {
        Long approver = null;
        // 选择厨师长审批
        List<Long> userId = sysUserPostMapper.getUserByPostId(11L);
        if (CollectionUtils.isEmpty(userId)) {
            approver = 1L;
        } else {
            approver = userId.get(0);
        }
        Approve approve = new Approve();
        approve.setActivityId(approveMission.getActivityId());
        approve.setActivityType(approveMission.getActivityType());
        approve.setApplicant(SecurityUtils.getUserId());
        approve.setApprover(approver);
        approve.setStatus("审批中");
        approve.setMissionId(approveMission.getId());
        approve.setName("自助餐菜单厨师长审批");
        approveMapper.insertApprove(approve);
    }

    private void handleNormalApprove(ApproveMission approveMission) {
        Long approver = null;
        // 选择厨师长审批
        List<Long> userId = sysUserPostMapper.getUserByPostId(11L);
        if (CollectionUtils.isEmpty(userId)) {
            approver = 1L;
        } else {
            approver = userId.get(0);
        }
        Approve approve = new Approve();
        approve.setActivityId(approveMission.getActivityId());
        approve.setActivityType(approveMission.getActivityType());
        approve.setApplicant(SecurityUtils.getUserId());
        approve.setApprover(approver);
        approve.setStatus("审批中");
        approve.setMissionId(approveMission.getId());
        approve.setName("点餐菜单厨师长审批");
        approveMapper.insertApprove(approve);
    }

    private void handleGarbageRecordApprove(ApproveMission approveMission) {
        Approve approve = new Approve();
        approve.setActivityId(approveMission.getActivityId());
        approve.setActivityType(approveMission.getActivityType());
        approve.setApplicant(SecurityUtils.getUserId());
        approve.setApprover(getFuKezhang(104L));
        approve.setStatus("审批中");
        approve.setMissionId(approveMission.getId());
        approve.setName("垃圾记录详情副科长审批");
        approveMapper.insertApprove(approve);

        approve.setId(null);
        approve.setApprover(getKezhang(104L));
        approve.setStatus(ApproveStatus.WAIT_PREVIOUS.getCode());
        approve.setName("垃圾记录详情科长审批");
        approveMapper.insertApprove(approve);
    }

    private void handleGoodsDetailApprove(ApproveMission approveMission) {
        Long approver = null;
        List<Long> userId = sysUserPostMapper.getUserByPostId(7L);
        if (CollectionUtils.isEmpty(userId)) {
            approver = 1L;
        } else {
            approver = userId.get(0);
        }
        Approve approve = new Approve();
        approve.setActivityId(approveMission.getActivityId());
        approve.setActivityType(approveMission.getActivityType());
        approve.setApplicant(SecurityUtils.getUserId());
        approve.setApprover(approver);
        approve.setStatus("审批中");
        approve.setMissionId(approveMission.getId());
        approve.setName("菜品信息详情科长审批");
        approveMapper.insertApprove(approve);
    }

    @Override
    public List<Approve> createApprove(Long activityId, ApproveActivityType activityType) {

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean approve(Long id) {
        Approve approve = approveMapper.selectById(id);
        Approve update = new Approve();
        update.setId(approve.getId());
        update.setApprover(SecurityUtils.getUserId());
        update.setApproveTime(java.sql.Timestamp.valueOf(LocalDateTime.now()));
        update.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        update.setStatus("通过");
        Boolean result = approveMapper.updateApprove(update) == 1;
        if (Boolean.FALSE.equals(result)) {
            return Boolean.FALSE;
        }

        //如果是盘点的-修改明细
        if (StringUtils.isNotBlank(approve.getActivityType())) {
            switch (approve.getActivityType()) {
                case "盘点审批":
                    storePanService.approvePassStorePan(approve.getActivityId());
                    break;
            }
        }

        List<Approve> approves = approveMapper.selectApproveList(Approve.builder().missionId(approve.getMissionId()).build());
        if (approves.stream().allMatch(a -> "通过".equals(a.getStatus()))) {
            ApproveMission approveMissionUpdate = new ApproveMission();
            approveMissionUpdate.setId(approve.getMissionId());
            approveMissionUpdate.setStatus("通过");
            approveMissionUpdate.setApproveTime(new Date());
            return approveMissionMapper.updateApproveMission(approveMissionUpdate) == 1;
        }
        for (int i = 0; i < approves.size(); i++) {
            if (!"通过".equals(approves.get(i).getStatus())) {
                continue;
            }
            Approve approveUpdate = new Approve();
            approveUpdate.setId(approves.get(i - 1).getId());
            approveUpdate.setStatus("审批中");
            approveMapper.updateApprove(approveUpdate);
            break;
        }
        return Boolean.TRUE;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deny(Long id) {
        Approve approve = approveMapper.selectById(id);
        Approve update = new Approve();
        update.setId(approve.getId());
        update.setApprover(SecurityUtils.getUserId());
        update.setApproveTime(java.sql.Timestamp.valueOf(LocalDateTime.now()));
        update.setUpdateBy(SecurityUtils.getLoginUser().getUser().getNickName());
        update.setStatus("拒绝");
        Boolean result = approveMapper.updateApprove(update) == 1;
        if (Boolean.FALSE.equals(result)) {
            return Boolean.FALSE;
        }
        ApproveMission approveMissionUpdate = new ApproveMission();
        approveMissionUpdate.setId(approve.getMissionId());
        approveMissionUpdate.setStatus("拒绝");
        approveMissionUpdate.setApproveTime(new Date());

        //如果是盘点的-修改明细
        if (StringUtils.isNotBlank(approve.getActivityType())) {
            switch (approve.getActivityType()) {
                case "盘点审批":
                    storePanService.approveRejectStorePan(approve.getActivityId());
                    break;
            }
        }
        return approveMissionMapper.updateApproveMission(approveMissionUpdate) == 1;
    }

    private Boolean checkPrevious(List<Long> previousIds) {
        List<Approve> previousApproves = approveMapper.selectByIds(previousIds);
        if (CollectionUtils.isEmpty(previousApproves)) {
            return Boolean.TRUE;
        }
        return previousApproves.stream().anyMatch(Approve::getApproved);
    }

    private void finishApproveMission(Long activityId, String activityType) {
        ApproveMission approveMission = approveMissionMapper.selectByActivity(activityId, activityType);
        if (approveMission == null) {
            throw new ServiceException("没有主任务");
        }
        ApproveMission approveMissionUpdate = ApproveMission.builder()
                .id(approveMission.getId())
                .approveTime(new Date())
                .status(ApproveStatus.DONE.getCode())
                .build();
        int result = approveMissionMapper.updateApproveMission(approveMissionUpdate);
        if (result == 0) {
            throw new ServiceException("更新主任务失败");
        }
    }

    private void changeAfterApprovesStatus(List<Long> afterIds) {
        if (CollectionUtils.isEmpty(afterIds)) {
            return;
        }
        Map<String, Object> params = new HashMap<>();
        params.put("ids", afterIds);
        params.put("status", ApproveStatus.WAITING.getCode());
        int result = approveMapper.batchUpdateApproveStatusByIds(params);
        if (result != afterIds.size()) {
            throw new ServiceException("更新下一层节点失败");
        }
    }

    private List<Long> transferToApproveIds(String idsString) {
        if (StringUtils.isBlank(idsString)) {
            return new ArrayList<>();
        }
        return Arrays.stream(idsString.split(",")).map(Long::valueOf).collect(Collectors.toList());
    }
}
